package com.deer.wms.ware.task.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.deer.wms.base.system.model.BillOutBO;
import com.deer.wms.base.system.model.BillOutDetailBO;
import com.deer.wms.base.system.model.Item.ItemInfo;
import com.deer.wms.base.system.model.PurchaseOrderBO;
import com.deer.wms.base.system.model.PurchaseOrderDetailBO;
import com.deer.wms.base.system.service.ItemInfoService;
import com.deer.wms.inventory.model.Inventory.Inventory;
import com.deer.wms.inventory.service.InventoryService;
import com.deer.wms.project.root.core.result.CommonCode;
import com.deer.wms.project.root.exception.ServiceException;
import com.deer.wms.project.root.service.SuperServiceImpl;
import com.deer.wms.project.root.util.DateUtils;
import com.deer.wms.system.manage.model.ware.WareInfo;
import com.deer.wms.system.manage.service.CodeRuleService;
import com.deer.wms.system.manage.service.WareInfoService;
import com.deer.wms.ware.task.dao.SoDetailMapper;
import com.deer.wms.ware.task.model.Return.SoLogItemDto;
import com.deer.wms.ware.task.model.SO.*;
import com.deer.wms.ware.task.model.SO.vo.SoDetailVo;
import com.deer.wms.ware.task.model.Wave.WaveDetail;
import com.deer.wms.ware.task.service.PickTaskService;
import com.deer.wms.ware.task.service.PushErpService;
import com.deer.wms.ware.task.service.SoDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.deer.wms.project.root.util.CollectionUtils.convertMap;
import static com.deer.wms.project.root.util.CollectionUtils.distinct;

/**
 * Created by guo on 2020/02/02.
 */
@Service
@Transactional
public class SoDetailServiceImpl extends SuperServiceImpl<SoDetailMapper, SoDetail> implements SoDetailService {

    @Autowired
    private SoDetailMapper soDetailMapper;
    @Autowired
    private SoMasterServiceImpl soMasterService;
    @Autowired
    private PickTaskService pickTaskService;
    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private SoMasterServiceImpl soMasterServiceImpl;
    @Autowired
    private ItemInfoService itemInfoService;
    @Autowired
    private PushErpService pushErpService;
    @Autowired
    private WareInfoService wareInfoService;
    @Autowired
    private WaveDetailServiceImpl waveDetailService;

    @Autowired
    private CodeRuleService codeRuleService;

    @Override
    public List<SoDetailDto> findList(SoDetailCriteria criteria) {
        return soDetailMapper.findList(criteria);
    }

    @Override
    public List<SoDetailDto> findBaoKuanByItemCode(String itemCode, Integer wareId, Integer orgId) {
        return soDetailMapper.findBaoKuanByItemCode(itemCode, wareId, orgId);
    }

    @Override
    public List<SoDetail> findByBillNo(String billNo) {
        return list(new QueryWrapper<SoDetail>().in("bill_no", billNo));

//        SoDetailVo soDetailVo = new SoDetailVo();
//        return soDetailMapper.findByBillNo(billNo);
    }

    /**
     * 同步最新的数据（如皋需求，因为可能期间发生变化）
     *
     *
     * @param soMasters@return List<SoDetail>
     */
    @Override
    public List<SoDetail> syncCurrentData(List<SoMaster> soMasters) {
        //List<SoMaster> soMasters = soMasterService.list(new QueryWrapper<SoMaster>().eq("wave_code", waveCode));
        for (SoMaster soMaster : soMasters) {
            System.out.println(soMaster.getBillNo());
        }
        if (ObjectUtil.isEmpty(soMasters)) {
            return null;
        }
        //老单据
        Set<String> oldBillNos = soMasters.stream().map(SoMaster::getBillNo).collect(Collectors.toSet());
        List<Integer> collect = soMasters.stream().map(SoMaster::getBeforeNum).collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>();
        map.put("billIds", collect);
        map.put("billTypeId", soMasters.iterator().next().getBillType());
        map.put("includeClosed", true);
        List<PurchaseOrderBO> po = pushErpService.GetAllIMSourceBills(map);
        if (ObjectUtil.isEmpty(po)) {
            return null;
        }
        Set<String> newBillSet = po.stream().map(item -> item.getBillNo()).collect(Collectors.toSet());

        Set<String> removeBill = newBillSet.stream().filter(item -> !oldBillNos.contains(item)).collect(Collectors.toSet());



        List<SoDetail> soDetailList = new ArrayList<>();
        List<PurchaseOrderDetailBO> billOutDetailBOS = new ArrayList<>();


        //Step2.表头字段遍历到表体中
        po.stream().map(item -> {
            item.setDetails(soMasterService.insertBillNo(item));
            billOutDetailBOS.addAll(item.getDetails());
            return item;
        }).collect(Collectors.toList());

        List<SoDetail> newDetail = new ArrayList<>();

        //Step6.获取所有物料
        Set<String> itemNumbers = billOutDetailBOS.stream().map(PurchaseOrderDetailBO::getItemNumber).collect(Collectors.toSet());
        if (ObjectUtil.isEmpty(itemNumbers)) {
            throw new ServiceException(CommonCode.BATCH_TACTIC_ERROR, "该单据已拆分新单据，不可同步拉取");
        }
        //获取所有物料
        List<ItemInfo> itemInfoList = itemInfoService.list(new QueryWrapper<ItemInfo>().in("item_code", itemNumbers));
        Map<String, List<PurchaseOrderDetailBO>> detailMap = billOutDetailBOS.stream().collect(Collectors.groupingBy(PurchaseOrderDetailBO::getBillNo));
        //Strep7.红蓝字对冲,同一单号,不同的类型 入库出库数量对冲
        List<PurchaseOrderDetailBO> merge = soMasterService.merge(detailMap);
//        List<BillOutDetailBO> merge = billOutDetailBOS.stream().filter(item -> item.getTargetBillROB()).collect(Collectors.toList());
        Map<String, ItemInfo> itemInfoMap = convertMap(itemInfoList, ItemInfo::getItemCode);
        List<String> notCategory = Arrays.asList("标准件", "标准件-MRP物料", "辅料-MRP物料", "辅料");
        for (PurchaseOrderDetailBO billOutDetailBO : merge) {


            if (billOutDetailBO.getItemNumber().equals("8S078404AA")) {
                System.out.println("1111");
            }
            ItemInfo itemInfo = itemInfoMap.get(billOutDetailBO.getItemNumber());
            String feedCateGory = Optional.ofNullable(itemInfo).map(item -> item.getFeedCategory()).orElse("");

            if (notCategory.contains(feedCateGory) && billOutDetailBO.getTargetBillTypeId() == 24) {
                continue;
            }
            SoDetail soDetail = new SoDetail();
            soDetail.setBillNo(billOutDetailBO.getBillNo());
            soDetail.setErpBillId(billOutDetailBO.getSourceBillId());
            soDetail.setBomSplit(billOutDetailBO.getRowIndex());//行号
            soDetail.setAllotPackDetailId(billOutDetailBO.getItemId());//物料ID
            soDetail.setItemCode(billOutDetailBO.getItemNumber());//物料编码
            soDetail.setItemName(billOutDetailBO.getItemName());//物料名称
            soDetail.setSpec(billOutDetailBO.getItemModel());//规格型号
            soDetail.setPickPackDetailId(33469);//辅助属性类别ID
            soDetail.setDeliveryPackDetailId(billOutDetailBO.getAuxPropId());//辅助属性ID
            soDetail.setModel(billOutDetailBO.getAuxPropName());//辅助属性
            soDetail.setPackDescribe(billOutDetailBO.getBatchManager() == null || billOutDetailBO.getBatchManager() == false ? "0" : "1");
            soDetail.setDetailNo(billOutDetailBO.getBatchNo());//批号
            soDetail.setPackDetailId(billOutDetailBO.getUnitId());//基本单位ID
            soDetail.setSoUdfDs2(billOutDetailBO.getUnitName());//单位
            soDetail.setOrderQuantity(billOutDetailBO.getOriginQty());//原始数量  变更数量
            soDetail.setPickQuantity(billOutDetailBO.getQcQty());
            soDetail.setStockId(billOutDetailBO.getStockId());
            soDetail.setAllottedQuantity(billOutDetailBO.getOriginQty() - billOutDetailBO.getQty());
            soDetail.setPickQuantity(billOutDetailBO.getOriginQty() - billOutDetailBO.getQty());
            soDetail.setDeliveryQuantity(billOutDetailBO.getOriginQty() - billOutDetailBO.getQty());

            soDetail.setSoUdfDs3(billOutDetailBO.getMtoNo());//计划跟踪号
            soDetail.setMemo(billOutDetailBO.getRemark());//备注
            soDetail.setPickPackDescribe(billOutDetailBO.getTargetBillTypeId().toString());//目标单据类型ID
            soDetail.setRob(billOutDetailBO.getTargetBillROB());
            if (soDetail.getOrderQuantity() < 0) {
                soDetail.setOrderQuantity(0 - soDetail.getOrderQuantity());
                soDetail.setRob(false);
            }
//            soDetail.setAllotPackDescribe(billOutDetailBO.getShelfLifeDays().toString());
            soDetail.setDeliveryPackDescribe(billOutDetailBO.getShelfLifeManager() == null || billOutDetailBO.getShelfLifeManager() == false ? "0" : "1");
            soDetail.setAllotDetailNo(billOutDetailBO.getProductionDate());
            soDetail.setTransRatio(1.00);

            soDetailList.add(soDetail);


        }
        return soDetailList;
    }

    public void syncCurentData(List<PurchaseOrderBO> bo) {
        if (ObjectUtil.isNotEmpty(bo)) {
            return;
        }
        List<SoMaster> soMasters = new ArrayList<>();
        List<SoDetail> soDetailList = new ArrayList<>();
        List<PurchaseOrderDetailBO> billOutDetailBOS = new ArrayList<>();
        //去重
        List<PurchaseOrderBO> po = distinct(bo, PurchaseOrderBO::getBillNo);
        //Step2.表头字段遍历到表体中
        po.stream().map(item -> {
            //表体履约号放在表头中
            item.setAgreementNo(item.getDetails().get(0).getAgreementNo());
            item.setDetails(soMasterService.insertBillNo(item));
            billOutDetailBOS.addAll(item.getDetails());
            return item;
        }).collect(Collectors.toList());
        //Step4.订单号去重
        Set<String> oldBillNos = po.stream().map(PurchaseOrderBO::getBillNo).collect(Collectors.toSet());
        //Step5.根据订单号过滤表里面已经有的数据(过滤)
        List<SoMaster> soMasterList = soMasterService.list(new QueryWrapper<SoMaster>().in("bill_no", oldBillNos));

//        this.first(billOutBOList);
        Set<String> newBillNos = soMasterList.stream().map(SoMaster::getBillNo).collect(Collectors.toSet());
        List<Integer> notBillNums = Arrays.asList(82, 251300022, 251300022, 251300058, 200000013);
        List<PurchaseOrderDetailBO> billOutBOS = soMasterService.filterDetaiBo(billOutDetailBOS, newBillNos, notBillNums);

        //Step6.获取所有物料
        Set<String> itemNumbers = billOutBOS.stream().map(PurchaseOrderDetailBO::getItemNumber).collect(Collectors.toSet());
        //获取所有物料
        List<ItemInfo> itemInfoList = itemInfoService.list(new QueryWrapper<ItemInfo>().in("item_code", itemNumbers));
        Map<String, List<PurchaseOrderDetailBO>> detailMap = billOutBOS.stream().collect(Collectors.groupingBy(PurchaseOrderDetailBO::getBillNo));


        //标准件
        List<String> notCategory = Arrays.asList("标准件", "标准件-MRP物料", "辅料-MRP物料", "辅料");
        //Strep7.红蓝字对冲,同一单号,不同的类型 入库出库数量对冲
        List<PurchaseOrderDetailBO> merge = soMasterService.merge(detailMap);
        Map<String, ItemInfo> itemInfoMap = convertMap(itemInfoList, ItemInfo::getItemCode);

        //Step
        Set<String> detailBillNo = new HashSet<>();
        for (PurchaseOrderDetailBO billOutDetailBO : merge) {
            ItemInfo itemInfo = itemInfoMap.get(billOutDetailBO.getItemNumber());
            //获取发料属性
            String feedCateGory = Optional.ofNullable(itemInfo).map(item -> item.getFeedCategory()).orElse("");
            //生产领料 通用件
            if (notCategory.contains(feedCateGory) && billOutDetailBO.getTargetBillTypeId() == 24) {
                continue;
            }
            SoDetail soDetail = new SoDetail();
            soDetail.setBillNo(billOutDetailBO.getBillNo());
            if (billOutDetailBO.getItemNumber().equals("8S078404AA")) {
                System.out.println("11111");
            }
            ;

            soDetail.setErpBillId(billOutDetailBO.getSourceBillId());
            soDetail.setBomSplit(billOutDetailBO.getRowIndex());//行号
            soDetail.setAllotPackDetailId(billOutDetailBO.getItemId());//物料ID
            soDetail.setItemCode(billOutDetailBO.getItemNumber());//物料编码
            soDetail.setItemName(billOutDetailBO.getItemName());//物料名称
            soDetail.setSpec(billOutDetailBO.getItemModel());//规格型号
            soDetail.setPackDetailId(33469);//辅助属性类别ID
            soDetail.setModel(billOutDetailBO.getAuxPropName());//辅助属性
            //批次管理
            soDetail.setPackDescribe(billOutDetailBO.getBatchManager() == null || billOutDetailBO.getBatchManager() == false ? "0" : "1");
            soDetail.setDetailNo(billOutDetailBO.getBillNo() + "-" + billOutDetailBO.getRowIndex());//批号
            soDetail.setPackDetailId(billOutDetailBO.getUnitId());//基本单位ID
            soDetail.setSoUdfDs2(billOutDetailBO.getUnitName());//单位
            soDetail.setOrderQuantity(billOutDetailBO.getOriginQty());//基本单位数量

            soDetail.setMergeNo(billOutDetailBO.getAgreementNo());
//                                soDetail.setAllotPackDescribe(billOutDetailBO.getPlanModeId().toString());//计划模式ID
            soDetail.setSoUdfDs3(billOutDetailBO.getMtoNo());//计划跟踪号
            soDetail.setMemo(billOutDetailBO.getRemark());//备注
            soDetail.setPickPackDescribe(billOutDetailBO.getTargetBillTypeId().toString());//目标单据类型ID
            //目标单据红蓝字
            soDetail.setRob(billOutDetailBO.getTargetBillROB());
//            soDetail.setAllotPackDescribe(billOutDetailBO.getShelfLifeDays().toString());
            soDetail.setDeliveryPackDescribe(billOutDetailBO.getShelfLifeManager() == null || billOutDetailBO.getShelfLifeManager() == false ? "0" : "1");
            soDetail.setAllotDetailNo(billOutDetailBO.getProductionDate());
            soDetail.setTransRatio(1.00);
            soDetailList.add(soDetail);
//            }

        }
//        List<DataDictDetail> dataDictDetails = dataDictDetailService.list(new QueryWrapper<DataDictDetail>().eq("data_dict_code", "else"));
//        Map<String, DataDictDetail> dataDictDetailMap = convertMap(dataDictDetails, DataDictDetail::getDictKey);


        Integer i = 0;
        //新增任务
        for (PurchaseOrderBO billOutBO : po) {

            SoMaster soMaster = new SoMaster();
            soMaster.setCreateTime(DateUtils.getNowDateTimeString());
            soMaster.setOrganizationId(86);//货主id
            soMaster.setSupplierName(billOutBO.getSupplierName()); // 供应商名称
            soMaster.setOrderBillNo(billOutBO.getOrderBillNo()); //订单号
            soMaster.setBeforeNum(billOutBO.getId());
            soMaster.setWareId(1);
            soMaster.setWareName("测试仓库");
            soMaster.setSoType(detailMap.get(billOutBO.getBillNo()).iterator().next().getTargetBillTypeId());
            soMaster.setBillType(billOutBO.getBillTypeId()); //单据类型id
//                            soMaster.setWareCode(billOutBO.getBillTypeName());//单据类型名称
            soMaster.setSoTypeName(billOutBO.getBillTypeName());//单据类型名称
            soMaster.setTradeNo(billOutBO.getAgreementNo());  //履约号
            soMaster.setBillNo(billOutBO.getBillNo());//单据编号
            //工业单据状态 0 - 草稿 1 - 已审核，未关联 2 - 已审批，部分关联 3 - 已审批，全部关联 生产任务单据状态 0 - 计划 5 - 确认 1 - 下达 3 - 结案 BOS单据状态 2 - 未审核 4 - 审核中 16 - 已审核
            soMaster.setOrganizationId(-1);
            soMaster.setOrganizationName("自有");
            soMaster.setOrganizationCode("SYS_MINE");
            soMaster.setDeptId(billOutBO.getDeptId());//部门ID
            soMaster.setDeptName(billOutBO.getDeptName());//部门名称

            //新增
            soMasters.add(soMaster);
        }
        List<SoMaster> collect = soMasters.stream().filter(item -> item.getBillNo().equals("00002641")).collect(Collectors.toList());
        //批量新增
//        soMasterService.different(billOutBOS);
        //合并物料编码一样的单据,物料编码一样的数量++
        //批量新增 soMaster
        soMasterService.saveBatch(soMasters);
        //批量新增 详情
        this.saveBatch(soDetailList);


    }

//    public List<SoDetail> syncCurrentData(String waveCode) {
//        List<WaveDetail> waveDetails = waveDetailService.list(new QueryWrapper<WaveDetail>().eq("wave_code", waveCode)
//                .ne("state", 0));
//        Set<Integer> waveDetailIds = waveDetails.stream().map(WaveDetail::getWaveDetailId).collect(Collectors.toSet());
//        List<SoDetail> oldDetail = new ArrayList<>();
//
//        //获取原来数据
//        if (ObjectUtil.isNotEmpty(waveDetailIds)) {
//            oldDetail = list(new QueryWrapper<SoDetail>().in("wave_detail_id", waveDetailIds));
//        }
//
//
//        List<SoMaster> soMasters = soMasterService.list(new QueryWrapper<SoMaster>().eq("wave_code", waveCode));
//        //老单据
//        Set<String> oldBillNos = soMasters.stream().map(SoMaster::getBillNo).collect(Collectors.toSet());
//        List<Integer> collect = soMasters.stream().map(SoMaster::getBeforeNum).collect(Collectors.toList());
//        Map<String, Object> map = new HashMap<>();
//        map.put("billIds", collect);
//        List<BillOutBO> po = pushErpService.OutSourceBill(map);
//        Set<String> newBillSet = po.stream().map(item -> item.getBillNo()).collect(Collectors.toSet());
//
//        Set<String> removeBill = newBillSet.stream().filter(item -> !oldBillNos.contains(item)).collect(Collectors.toSet());
//
//        if (ObjectUtil.isNotEmpty(removeBill)) {
//            //删除原数据
//            soMasterService.remove(new QueryWrapper<SoMaster>().in("bill_no", removeBill));
//        }
//
//        List<Integer> notBillNums = Arrays.asList(82, 251300022, 251300022, 251300058, 200000013);
//        List<SoDetail> soDetailList = new ArrayList<>();
//        List<BillOutDetailBO> billOutDetailBOS = new ArrayList<>();
//
//
//        //Step2.表头字段遍历到表体中
//        po.stream().map(item -> {
////            item.setDetails(soMasterService.insertBillNo(item));
//            billOutDetailBOS.addAll(item.getDetails());
//            return item;
//        }).collect(Collectors.toList());
//
//        List<SoDetail> newDetail = new ArrayList<>();
//
//        //Step6.获取所有物料
//        Set<String> itemNumbers = billOutDetailBOS.stream().map(BillOutDetailBO::getItemNumber).collect(Collectors.toSet());
//        //获取所有物料
//        List<ItemInfo> itemInfoList = itemInfoService.list(new QueryWrapper<ItemInfo>().in("item_code", itemNumbers));
//        Map<String, List<BillOutDetailBO>> detailMap = billOutDetailBOS.stream().collect(Collectors.groupingBy(BillOutDetailBO::getBillNo));
//        //Strep7.红蓝字对冲,同一单号,不同的类型 入库出库数量对冲
//        List<BillOutDetailBO> merge = soMasterService.merge(detailMap);
//        for (BillOutDetailBO billOutDetailBO : merge) {
//
//            ItemInfo itemInfo = itemInfoList.stream().filter(item -> item.getItemCode().equals(billOutDetailBO.getItemNumber())).collect(Collectors.toList()).get(0);
//            if (itemInfo.getCategory() != "标准件" && itemInfo.getCategory() != "标准件-MRP物料" && itemInfo.getCategory() != "辅料-MRP物料" && itemInfo.getCategory() != "辅料") {
//
//
//                SoDetail soDetail = new SoDetail();
//                soDetail.setBillNo(billOutDetailBO.getBillNo());
//                soDetail.setErpBillId(billOutDetailBO.getSourceBillId());
//                soDetail.setBomSplit(billOutDetailBO.getRowIndex());//行号
//                soDetail.setAllotPackDetailId(billOutDetailBO.getItemId());//物料ID
//                soDetail.setItemCode(billOutDetailBO.getItemNumber());//物料编码
//                soDetail.setItemName(billOutDetailBO.getItemName());//物料名称
//                soDetail.setSpec(billOutDetailBO.getItemModel());//规格型号
//                soDetail.setPickPackDetailId(billOutDetailBO.getAuxPropClassId());//辅助属性类别ID
//                soDetail.setDeliveryPackDetailId(billOutDetailBO.getAuxPropId());//辅助属性ID
//                soDetail.setModel(billOutDetailBO.getAuxPropName());//辅助属性
//                soDetail.setPackDescribe(billOutDetailBO.getBatchManager() == null || billOutDetailBO.getBatchManager() == false ? "0" : "1");
//                soDetail.setDetailNo(billOutDetailBO.getBatchNo());//批号
//                soDetail.setPackDetailId(billOutDetailBO.getUnitId());//基本单位ID
//                soDetail.setSoUdfDs2(billOutDetailBO.getUnitName());//单位
//                soDetail.setOrderQuantity(billOutDetailBO.getQty());//基本单位数量
//                soDetail.setPickQuantity(billOutDetailBO.getQcQty());
//                soDetail.setSoUdfDs3(billOutDetailBO.getMtoNo());//计划跟踪号
//                soDetail.setMemo(billOutDetailBO.getRemark());//备注
//                soDetail.setPickPackDescribe(billOutDetailBO.getTargetBillTypeId().toString());//目标单据类型ID
//                soDetail.setRob(billOutDetailBO.getTargetBillROB());
//                soDetail.setAllotPackDescribe(billOutDetailBO.getShelfLifeDays().toString());
//                soDetail.setDeliveryPackDescribe(billOutDetailBO.getShelfLifeManager() == null || billOutDetailBO.getShelfLifeManager() == false ? "0" : "1");
//                soDetail.setAllotDetailNo(billOutDetailBO.getProductionDate());
//                soDetail.setTransRatio(1.00);
//                if (!oldDetail.contains(soDetail)) {
//                    soDetailList.add(soDetail);
//                } else {
//                    newDetail.add(soDetail);
//                }
//            }
//
//        }
////        //新增出库任务单
////        if (ObjectUtil.isNotEmpty(newDetail)) {
////            saveSo(newDetail, po);
////        }
//        return soDetailList;
//    }

    public void saveSo(List<SoDetail> newDetail, List<BillOutBO> po) {
        List<SoMaster> soMasters = new ArrayList<>();
        Set<String> collect = newDetail.stream().map(SoDetail::getBillNo).collect(Collectors.toSet());
        Set<SoDetail> addDetail = new HashSet<>();
        //Step0.准备数据
        Integer wareId = 285;
        List<WareInfo> wareInfoList = wareInfoService.list();
        Map<Integer, WareInfo> wareInfoMap = wareInfoList.stream().collect(Collectors.toMap(WareInfo::getWareId, wareInfo -> wareInfo, (oldValue, newValue) -> newValue));
        Map<String, SoDetail> detailMap = newDetail.stream().collect(Collectors.toMap(SoDetail::getBillNo, detail -> detail, (oldValue, newValue) -> newValue));

        for (BillOutBO billOutBO : po) {
            if (!collect.contains(billOutBO.getBillNo())) {
                continue;
            }
            SoMaster soMaster = new SoMaster();
            soMaster.setCreateTime(DateUtils.getNowDateTimeString());
            soMaster.setOrganizationId(86);//货主id
            soMaster.setWareId(wareId);//仓库id
            soMaster.setWareCode(wareInfoMap.get(wareId).getWareCode());
            soMaster.setWareName(wareInfoMap.get(wareId).getWareName());
            soMaster.setSupplierId(billOutBO.getSupplierId());//供应商id
            soMaster.setSupplierName(billOutBO.getSupplierName()); // 供应商名称
            soMaster.setOrderBillNo(codeRuleService.generateCodeByRedis("OUT")); //订单号
            soMaster.setBeforeNum(billOutBO.getId());
            soMaster.setSoType(detailMap.get(billOutBO.getBillNo()).getPackDetailId()); ///单据类型id
            soMaster.setBillType(billOutBO.getBillTypeId()); //单据类型id
            soMaster.setSoTypeName(billOutBO.getBillTypeName());//单据类型名称
            soMaster.setTradeNo(billOutBO.getAgreementNo());  //履约号
            soMaster.setBillNo(billOutBO.getBillNo());//单据编号
            soMaster.setShipCode(billOutBO.getBillDate());//单据日期
            soMaster.setCarrierId(billOutBO.getBillStatus());//工业单据状态
            soMaster.setIsClose(billOutBO.getBillClosed() == null || billOutBO.getBillClosed() == false ? 0 : 1);//关闭状态
            soMaster.setOrganizationId(-1);
            soMaster.setOrganizationName("自有");
            soMaster.setOrganizationCode("SYS_MINE");
            soMaster.setOrderBillId(billOutBO.getOrderBillId());
            soMaster.setDeptId(billOutBO.getDeptId());//部门ID
            soMaster.setDeptName(billOutBO.getDeptName());//部门名称
            soMaster.setMemo(billOutBO.getRemark());//备注
            soMaster.setExpectTimeFm(billOutBO.getPlanStartDate());//计划开工日期
            soMaster.setCustomerId(billOutBO.getCustomerId());//客户ID
            soMaster.setCustomerName(billOutBO.getCustomerName());//客户名称
            //新增
            soMasters.add(soMaster);
            //详情
            List<SoDetail> soDetails = newDetail.stream().filter(item -> item.getErpBillId() == soMaster.getBeforeNum()).map(menu -> {
                menu.setBillNo(soMaster.getBillNo());
                return menu;
            }).collect(Collectors.toList());
            addDetail.addAll(soDetails);
        }
        soMasterService.saveBatch(soMasters);
        saveBatch(addDetail);

    }

    @Override
    public List<SoDetailDto> findUndistributedSoDetail(Integer soType) {
        return soDetailMapper.findUndistributedSoDetail(soType);
    }

    @Override
    public List<SoDetail> findByMasterId(Integer soId) {
        return soDetailMapper.findByMasterId(soId);
    }

    @Override
    public List<SoDayList> findDayList(SoDetailCriteria criteria) {
        return soDetailMapper.findDayList(criteria);
    }

    @Override
    public List<SoLogItemDto> findLogItemsByBillNos(List<String> billNos) {
        return soDetailMapper.findLogItemsByBillNos(billNos);
    }

    @Override
    public List<SoDetailDto> findDetailsByWaveId(Integer wareId, Integer waveId) {
        return soDetailMapper.findDetailsByWaveId(wareId, waveId);
    }

    /**
     * 查询借料项 全部项
     *
     * @param billNo
     * @return
     */
    @Override
    public SoDetailVo findAll(String billNo) {
        SoDetailVo soDetailVo = new SoDetailVo();
        List<SoDetail> soDetailList = list(new QueryWrapper<SoDetail>().eq("bill_no", billNo));
        if (ObjectUtil.isNotEmpty(soDetailList)) {
            soDetailVo.setAll(soDetailList); // 全部项
            soDetailVo.setLend(this.lendDetail(soDetailList));//借料项
        }
        return soDetailVo;
    }


    /**
     * @param inventoryList 库存余量表
     * @param itemCode      物料编码
     * @return
     */
    public Double putNumber(List<Inventory> inventoryList, String itemCode, Integer organizationId) {
        //入库数量-分配数量 -冻结数量   //货主id 88货主Id默认为 -1 自有, code SYS_MINE
        return inventoryList.stream().filter(item -> item.getItemCode().equals(itemCode) && item.getOrganizationId() == organizationId).mapToDouble(item ->
                item.getQuantity() - item.getAllotQuantity() - item.getFreezeQuantity()
        ).sum();

    }

    /**
     * 获取所有数据
     *
     * @param billNo
     * @return
     */
    @Override
    public List<SoDetail> findByOrderNo(String billNo) {
        return baseMapper.findByOrderNo(billNo);
    }

    /**
     * 过滤单号查询数据
     *
     * @param itemCode
     * @param billNo
     * @return
     */
    @Override
    public List<SoDetail> beBeing(String itemCode, String billNo) {
        return baseMapper.beBeing(itemCode, billNo);
    }

    @Override
    public void contrastSoDetail(List<SoDetail> allSoDetails, Map<SoDetail, SoDetail> newMap, Map<SoDetail, SoDetail> oldMap) {
        for (SoDetail key : allSoDetails) {
            if (key.getItemCode().equals("12.09.0157")) {
                System.out.println("1111111");
            }
            SoDetail newSd = newMap.get(key);
            SoDetail oldSd = oldMap.get(key);
            if (newSd == null) {
                //如果已经复核，回传给ERP则不需要改变
                if (oldSd.getOrderQuantity() - oldSd.getPickQuantity() <= 0) {
                    continue;
                }
                //如果老单子删除
                removeById(oldSd.getSoDetailId());
                WaveDetail waveDetail = waveDetailService.getById(oldSd.getWaveDetailId());
                if (ObjectUtil.isEmpty(waveDetail)) {
                    continue;
                }
                //已分配
                if (waveDetail.getQuantity() > oldSd.getOrderQuantity()) {
                    waveDetail.setQuantity(waveDetail.getQuantity() - oldSd.getOrderQuantity());
                    waveDetailService.updateById(waveDetail);
                } else {
                    waveDetailService.removeById(waveDetail);
                }
            } else if (ObjectUtil.isEmpty(oldSd)) {
                //如果老单子为空则新增一条
                newSd.setState(0);
                this.save(newSd);
                ;
            } else {
                //同步仓库
                oldSd.setStockId(newSd.getStockId());
                //都有，则判断数量，有变化则修改
                if (ObjectUtil.notEqual(oldSd.getOrderQuantity(), newSd.getOrderQuantity())) {
                    Double newQty = newSd.getOrderQuantity();
                    Double oldQty = oldSd.getOrderQuantity();
                    oldSd.setOrderQuantity(newQty);
                }
                this.updateById(oldSd);
            }
        }
    }


    //获取供料项
    public List<SoDetail> lendDetail(List<SoDetail> list) {
        Set<String> itemCodes = list.stream().map(SoDetail::getItemCode).collect(Collectors.toSet());
        //查找库存
        List<Inventory> inventories = inventoryService.list(new QueryWrapper<Inventory>().in("item_code", itemCodes)
                .ne("cell_code", 28500)
        );
        Map<String, List<Inventory>> invMap = inventories.stream().collect(Collectors.groupingBy(Inventory::getItemCode));
        return list.stream().filter(item -> item.getOrderQuantity() > item.getDeliveryQuantity())
                .map(item -> {
                    //库存数量
                    item.setTotalNum(
                            ObjectUtil.isNotEmpty(invMap.get(item.getItemCode()))
                                    ?
                                    invMap.get(item.getItemCode()).stream()
                                            .mapToDouble(menu -> {return menu.getQuantity() - menu.getAllotQuantity();
                                            }).sum()
                                    : 0.00
                    );
                    return item;
                })
                .collect(Collectors.toList());
    }


}
